package com.smm.web.mtower.bo;

import com.smm.web.mtower.domain.Camera;
import com.smm.web.mtower.util.HCNetSDK;
import com.smm.web.mtower.util.HCNetSDKInit;
import com.smm.web.mtower.util.RealDataCallBack;
import com.sun.jna.NativeLong;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

/**
 * Created by zhenghao on 2016/6/13.
 *
 */
@Service
public class CameraBO {

    private static final Logger logger= Logger.getLogger(CameraBO.class);



    /**
     * 抓拍方法
     * @param camera            摄像头对象
     * @param imageSavePath     抓拍图片保存物理位置，包含图片名称
     * @throws Exception
     */
    public void sanp(Camera camera, String imageSavePath) throws Exception {

        HCNetSDK hCNetSDK=null;

        NativeLong lUserID = null;

        try {
            hCNetSDK = HCNetSDKInit.newInstance();

            boolean m_bInitSDK = hCNetSDK.NET_DVR_Init();

            if (!m_bInitSDK) {
                logger.info("SDK初始化失败,请检查SDK路径是否正确.");
                throw new Exception("sdk 初始化失败");
            }

            lUserID = new NativeLong();// 用户句柄

            logger.info("lUserID.longValue:"+lUserID.longValue());
            /**
             * 注册之前先注销已注册的用户
             */
            if (lUserID.longValue() > -1) {
                logger.info(camera.getIp()+"注册之前先注销已注册的用户");
                hCNetSDK.NET_DVR_Logout_V30(lUserID);
//				lUserID = new NativeLong(-1);
            }
            /**
             * 注册设备
             */
            HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();


            logger.info("登陆参数: ip="+camera.getIp()+"  port="+camera.getPort()+"  username="+camera.getAccount()+"  password="+camera.getPassword());


            lUserID = hCNetSDK.NET_DVR_Login_V30(camera.getIp(),Short.parseShort(camera.getPort()), camera.getAccount(),camera.getPassword(), m_strDeviceInfo);



            if (lUserID.longValue() == -1) {

                logger.error(camera.getIp() + " 登录失败.");

                throw new Exception(camera.getIp() + " 登录失败.错误类型："+hCNetSDK.NET_DVR_GetLastError());

            }else {

                logger.info(camera.getIp() + " 登录成功. 开始抓拍图片");
            }


            /**
             * 登录成功，开始抓图
             */
            NativeLong lChannel = new NativeLong(1);// 通道号 Channel number
            HCNetSDK.NET_DVR_JPEGPARA net_dvr_jpegpara = new HCNetSDK.NET_DVR_JPEGPARA();


            /**
             * 抓拍参数
             * wPicSize     图片尺寸：0-CIF(352*288/352*240)，1-QCIF(176*144/176*120)，2-4CIF(704*576/704*480)或D1(720*576/720*486)，3-UXGA(1600*1200)，
             4-SVGA(800*600)，5-HD720P(1280*720)，6-VGA(640*480)，7-XVGA(1280*960)，8-HD900P(1600*900)，9-HD1080P(1920*1080)，10-2560*1920，
             11-1600*304，12-2048*1536，13-2448*2048，14-2448*1200，15-2448*800，16-XGA(1024*768)，17-SXGA(1280*1024)，18-WD1(960*576/960*480),
             19-1080I(1920*1080)，20-576*576，21-1536*1536，22-1920*1920，0xff-Auto(使用当前码流分辨率)
             wPicQuality    图片质量系数：0-最好，1-较好，2-一般
             */
            net_dvr_jpegpara.wPicSize = (short) 0xff;
            net_dvr_jpegpara.wPicQuality = 2;

            logger.info("抓拍参数: lUserID="+lUserID.longValue()+"  lChannel="+lChannel+"  fileName="+imageSavePath);

            if (hCNetSDK.NET_DVR_CaptureJPEGPicture(lUserID, lChannel,net_dvr_jpegpara, imageSavePath)) {

                logger.info(camera.getIp()+" 抓拍成功.保存在:" + imageSavePath);

            }else{
                logger.info(camera.getIp()+" 抓拍失败.错误类型：" +hCNetSDK.NET_DVR_GetLastError());

                throw new Exception(camera.getIp()+" 抓拍失败.错误类型：" +hCNetSDK.NET_DVR_GetLastError());
            }

        } catch (Exception e) {
            logger.error("调用摄像头失败异常.",e);
            throw  e;
        }finally {

            if(lUserID != null) hCNetSDK.NET_DVR_Logout(lUserID);

            logger.info("用户退出登录");

            if(hCNetSDK != null) hCNetSDK.NET_DVR_Cleanup();

            logger.info("sdk 释放完成");

        }

    }


    /**
     * 播放执行摄像头视频
     * @param camera    摄像头对象
     */
    public void mediaPlay(Camera camera){

        HCNetSDK hCNetSDK = null;

        NativeLong lUserID = null;

        try{

            //初始化 sdk
            hCNetSDK = HCNetSDKInit.newInstance();

            hCNetSDK.NET_DVR_Init();

            logger.info(" sdk 初始化 成功");

            //设置网络连接超时时间，重连次数
            hCNetSDK.NET_DVR_SetConnectTime(10*1000, 1);

            //设置重连间隔时间
            hCNetSDK.NET_DVR_SetReconnect(20*1000, true);

            //设备信息对象，调用登录方法后赋值。
            HCNetSDK.NET_DVR_DEVICEINFO_V30 lpDeviceInfo =new HCNetSDK.NET_DVR_DEVICEINFO_V30();

            //用户登录
            lUserID = hCNetSDK.NET_DVR_Login_V30(camera.getIp(),Short.parseShort(camera.getPort()), camera.getAccount(),camera.getPassword(),lpDeviceInfo);

            //显示设备信息
            logger.info(lpDeviceInfo);

            logger.info("用户登录完成。 userId:"+lUserID.intValue());

            if(lUserID.intValue()<0) throw new Exception("登录失败。错误编码："+ hCNetSDK.NET_DVR_GetLastError());

            //启动预览

            /**
             * NET_DVR_CLIENTINFO
             * Members
                 lChannel
                    通道号，1~32表示模拟通道1~32，9000系列混合型DVR和NVR等设备的IP通道从33开始。
                 lLinkMode
                    最高位(31)为0表示主码流，为1表示子码流；0～30位表示连接方式：0－TCP方式，1－UDP方式，2－多播方式
                    例如子码流TCP连接，则lLinkMode=0x80000000
                 hPlayWnd
                    播放窗口的句柄，为NULL表示不显示图像
                 sMultiCastIP
                    多播组地址

             */
            HCNetSDK.NET_DVR_CLIENTINFO lpClientInfo = new HCNetSDK.NET_DVR_CLIENTINFO();
            lpClientInfo.lChannel=new NativeLong(lpDeviceInfo.byStartChan);//new NativeLong(lpDeviceInfo.byStartChan);
            lpClientInfo.lLinkMode = new NativeLong(0x80000000);
//            lpClientInfo.lLinkMode = new NativeLong(0x0);
            lpClientInfo.hPlayWnd = null;
            lpClientInfo.sMultiCastIP = null;



            /**
             * NET_DVR_RealPlay_V30
             * Parameters
                 lUserID
                    [in] NET_DVR_Login_V40等登录接口的返回值
                 lpClientInfo
                    [in] 预览参数
                 cbRealDataCallBack
                    [in] 码流数据回调函数
                 pUser
                    [in] 用户数据
                 bBlocked
                    [in] 请求码流过程是否阻塞：0－否；1－是
             */
            NativeLong lRealPlayHandle  = hCNetSDK.NET_DVR_RealPlay_V30(lUserID, lpClientInfo, new RealDataCallBack(),null,true);

            //获取视频码流
            logger.info("播放视频 playHandle:"+lRealPlayHandle.longValue());

            if(lRealPlayHandle.longValue()<0) throw new Exception("播放视频失败。错误编码：" +hCNetSDK.NET_DVR_GetLastError());

            //停止播放
            hCNetSDK.NET_DVR_StopRealPlay(lRealPlayHandle);

            logger.info("停止播放");

        }catch (Exception e){

            e.printStackTrace();

            logger.error(e);

        }finally {

            if(lUserID != null) hCNetSDK.NET_DVR_Logout(lUserID);

            logger.info("用户退出登录");

            if(hCNetSDK != null) hCNetSDK.NET_DVR_Cleanup();

            logger.info("sdk 释放完成");

        }


    }


    public static void main(String[] args) throws Exception{

        CameraBO cameraBO = new CameraBO();

        Camera camera = new Camera();

        camera.setIp("172.16.81.241");

//        camera.setIp("192.168.8.250");

        cameraBO.mediaPlay(camera);


    }






}
